﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Microsoft.Win32;
using System.Windows;
using System.Xml;
using SHomeWorkshop.LunarConcept.Controls;
using SHomeWorkshop.LunarConcept.Tools;
using WinForm = System.Windows.Forms;
using SHomeWorkshop.LunarConcept.ModifingManager;
using System.IO;
using SHomeWorkshop.LunarConcept.Widgets.Interfaces;

namespace SHomeWorkshop.LunarConcept.Commands
{
    /// <summary>
    /// 创建时间：2012年1月19日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：粘贴部件命令。不允许跨页面复制、剪切和粘贴——但允许跨页删除部件！！
    /// ★★说明：关于自定义命令的实现，可参考“NewDocument”类的备注。
    /// </summary>
    public static class PasteCommand
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// ★②，修改静态构造方法名。
        /// </summary>
        static PasteCommand()//类型构造器
        {
            //★③，修改两个字符串参数名。★④以及第三个参数的类型名。
            routedUICmd = new RoutedUICommand(
                "PasteCommand",
                "PasteCommand",
                typeof(PasteCommand),//创建RoutedUICommand对象
                null);

            routedUICmd.InputGestures.Add(new KeyGesture(Key.V, ModifierKeys.Control, "Ctrl + V"));

            //如果需要挂接快捷键，请参考下面这段代码：
            //routedUICmd = new RoutedUICommand(
            //    "SaveDocumentCommand",
            //    "SaveDocumentCommand",
            //    typeof(SaveDocumentCommand),//创建RoutedUICommand对象
            //    new InputGestureCollection() 
            //    { 
            //        //★⑤，修改此处三个参数，以便挂接快捷键。
            //        new KeyGesture(Key.S,ModifierKeys.Control,"Ctrl+S")
            //    });

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        #endregion

        #region 字段与属性===================================================================================================

        private static CommandBinding cmdBinding = new CommandBinding();
        /// <summary>
        /// 用在主窗口CommandBindings集合中的命令绑定。
        /// 
        /// 它的Command是RoutedUICommand。
        /// ——因此，RoutedUICommand是否可以运行将由CmdBinding的CanExecute事件决定。
        /// ——而且，RoutedUICommand的执行也是通过CmdBinding的Execute事件来进行的。
        /// </summary>
        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        private static RoutedUICommand routedUICmd;
        /// <summary>
        /// [只读静态属性]表示在WPF系统中注册的一个RoutedUICommand。
        /// ——必须和CommandBinding配合才能使用。
        ///     CommandBinding要添加到主窗口的CommandBindings集合中；
        ///     RoutedUICommand则要向WPF系统注册。
        ///     
        /// ★说明：使用静态属性是因为这样在Xaml代码中比较便于绑定。
        /// </summary>
        public static RoutedUICommand RoutedUICmd
        {
            get { return routedUICmd; }
        }

        #endregion

        #region 方法=========================================================================================================

        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //★⑧，修改此方法的实现。

            //考虑到性能问题，全部取消此判断。反正执行时会判断。
            //if (Globals.MainWindow == null) { e.CanExecute = false; return; }

            //try
            //{
            //    string text = Clipboard.GetText(TextDataFormat.UnicodeText);

            //    if (text != null && text.Length > 0)
            //    {
            //        if (text.StartsWith("<LunarConcept.Copy") &&
            //            text.EndsWith("</LunarConcept.Copy>"))
            //        {
            //            XmlDocument doc = new XmlDocument();
            //            doc.LoadXml(XmlTools.XmlHeaderText + text);

            //            if (doc.DocumentElement == null)
            //            {
            //                e.CanExecute = false;
            //                return;
            //            }

            //            if (doc.DocumentElement.HasChildNodes == false)
            //            {
            //                e.CanExecute = false;
            //                return;
            //            }

            //            e.CanExecute = true;
            //            return;
            //        }
            //    }
            //    else
            //    {
            //        WinForm.IDataObject oDataObj = WinForm.Clipboard.GetDataObject();
            //        if (oDataObj != null)
            //        {
            //            if (oDataObj.GetDataPresent(DataFormats.Bitmap) == false)
            //            {
            //                e.CanExecute = false;
            //                return;
            //            }
            //            //这个准备用来粘贴图片
            //            e.CanExecute = true;
            //            return;
            //        }
            //    }
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show("　　发生意外，未能取出剪贴板中的数据！系统剪贴板可能被其它程序占用。" +
            //        "异常信息如下：\r\n" +
            //        ex.Message + "\r\n" + ex.StackTrace, Globals.AppName,
            //        MessageBoxButton.OK, MessageBoxImage.Warning);
            //    return;
            //}

            e.CanExecute = true;
            return;
        }

        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //★⑦，修改此方法的实现。

            LunarMessage.Warning(Execute());
        }

        /// <summary>
        /// [公开静态方法]即使此命令处于禁用状态，也可以通过代码调用此方法来执行特定任务！！！
        /// 
        /// 当被绑定的命令被调用（触发）时，会引发cmdBinding_Executed事件。
        /// 在cmdBinding_Executed事件处理器方法中已添加了调用Execute()方法的代码。
        /// 
        /// ——因此，触发命令，就相当于调用此方法！！！
        /// </summary>
        public static string Execute(string copiedWidgetsXml = null, Point? topLeft = null)
        {
            if (Globals.MainWindow == null) return "　　未找到Globals.MainWindow。";
            EditorManager manager = Globals.MainWindow.EditorManager;
            if (manager == null) return "　　未找到页面管理器。";
            PageEditor mainPe = Globals.MainWindow.EditorManager.GetMainSelectedPageEditor();
            if (mainPe == null) return "　　未选定页面。";

            var clipboardText = Clipboard.GetText(TextDataFormat.UnicodeText);
            if ((clipboardText.StartsWith("<LunarMind.PictureBox><PictureBox") &&
                clipboardText.EndsWith("</LunarConcept></PictureBox></LunarMind.PictureBox>")) ||
                (clipboardText.StartsWith("<LunarMind.Xaml>") && clipboardText.EndsWith("</LunarMind.Xaml>")))
            {
                return InserdCopiedBackConceptPage(manager, mainPe, clipboardText);
            }

            if (copiedWidgetsXml == null)
            {
                //先判断要粘贴的是否图像数据块
                try
                {
                    WinForm.IDataObject oDataObj = WinForm.Clipboard.GetDataObject();
                    if (oDataObj != null)
                    {
                        if (oDataObj.GetDataPresent(DataFormats.Bitmap))
                        {
                            System.Drawing.Image oImgObj = oDataObj.GetData(DataFormats.Bitmap, true) as System.Drawing.Image;
                            PasteImageData(oImgObj);
                            return string.Empty;
                        }
                    }
                }
                catch (Exception ex)
                {
                    return "　　发生意外，未能取出剪贴板中的数据！系统剪贴板可能被其它程序占用（例如迅雷的“监视剪贴板”功能）。" +
                        "异常信息如下：\r\n" + ex.Message + "\r\n" + ex.StackTrace;
                }
            }

            try
            {
                string text;
                if (copiedWidgetsXml == null)
                {
                    text = Clipboard.GetText(TextDataFormat.UnicodeText);
                }
                else { text = copiedWidgetsXml; }

                Point insertPoint;
                if (topLeft == null)
                {
                    insertPoint = mainPe.BaseInsertPoint;
                }
                else
                {
                    insertPoint = topLeft.Value;
                }

                if (text != null && text.Length > 0)
                {
                    var txt = text.Trim(new char[] { '\r', '\n', '\t', ' ', });
                    if (txt.StartsWith("<Viewbox ") && txt.EndsWith("</Viewbox>"))
                    {
                        var widgets = mainPe.GetSelectedWidgetsList();
                        var picBoxCount = 0;
                        var rectangleCount = 0;
                        foreach(var widget in widgets)
                        {
                            switch (widget.WidgetType)
                            {
                                case Enums.WidgetTypes.PictureBox:
                                    {
                                        picBoxCount++;
                                        break;
                                    }                                  
                                case Enums.WidgetTypes.Rectangle:
                                    {
                                        rectangleCount++;
                                        break;
                                    }
                            }
                        }

                        if (picBoxCount <= 0 && rectangleCount <= 0)
                        {
                            if(Commands.InsertPictureBoxCommand.Execute()== string.Empty)
                            {
                                return Commands.SetXamlIconCommand.Execute();
                            }
                        }
                        else
                        {
                            var result = Commands.SetXamlIconCommand.Execute();
                            result += Commands.SetRectangleIconXamlTextCommand.Execute(txt);
                            return result;
                        }
                    }

                    if (text.StartsWith("<LunarConcept.CopiedPages") &&
                        text.EndsWith("</LunarConcept.CopiedPages>"))
                    {
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(XmlTools.XmlHeaderText + text);

                        if (doc.DocumentElement == null) return "　　无法理解要粘贴的文本的Xml结构。";
                        if (doc.DocumentElement.HasChildNodes == false)
                        {
                            return "　　剪贴板中复制的数据并未携带可粘贴的内容！";
                        }

                        var pageXmlNodeList = doc.DocumentElement.ChildNodes;
                        return InsertNewPageEditorCommand.Execute(pageXmlNodeList);
                    }
                    else if (text.StartsWith("<LunarConcept.Copy") &&
                        text.EndsWith("</LunarConcept.Copy>"))
                    {
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(XmlTools.XmlHeaderText + text);

                        if (doc.DocumentElement == null) return "　　无法理解要粘贴的文本的Xml结构。";
                        if (doc.DocumentElement.HasChildNodes == false)
                        {
                            return "　　剪贴板中复制的数据并未携带可粘贴的内容！";
                        }

                        double needWidth = double.Parse(doc.DocumentElement.GetAttributeValueText("Width"));
                        double needHeight = double.Parse(doc.DocumentElement.GetAttributeValueText("Height"));

                        double pageWidth = mainPe.ActualWidth;
                        double pageHeight = mainPe.ActualHeight;

                        if (pageWidth - insertPoint.X < needWidth ||
                            pageHeight - insertPoint.Y < needHeight)
                        {
                            return "　　需要更大的空间。请将插入点向页面左上角移动一段距离。";
                        }

                        XmlNodeList widgetNodeList = doc.DocumentElement.SelectNodes("Widget");

                        if (widgetNodeList == null || widgetNodeList.Count <= 0)
                        {
                            return "　　没有找到用来生成部件副本的Xml文本数据。";
                        }

                        ModifingInfo info = new ModifingInfo() { ModifingDescription = "粘贴或生成部件副本" };
                        manager.GetSelectedPageEditorStatus(info);
                        manager.GetSelectedWidgetStatus_Old(info);
                        ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

                        manager.ClearWidgetsSelection();

                        XmlNode mainDocWidgetSetNode = mainPe.XmlData.SelectSingleNode("WidgetSet");
                        if (mainDocWidgetSetNode == null)
                        {
                            return "　　没找到当前页的“WidgetSet”节点。";
                        }

                        List<Widgets.Widget> pastedOtherWidgets = new List<Widgets.Widget>();//除ICanBeLinkedWidget和ILinkableLine以外的其它部件。
                        List<ILinkableLine> pastedLinkableLines = new List<ILinkableLine>();
                        List<ICanBeLinkedWidget> pastedCanLindedWidgets = new List<ICanBeLinkedWidget>();

                        foreach (XmlNode node in widgetNodeList)
                        {
                            XmlNode newWidgetNode = mainDocWidgetSetNode.AppendXmlAsChild(node.OuterXml);
                            if (newWidgetNode != null)
                            {
                                Widgets.Widget w = Widgets.Widget.BuildWidget(mainPe, newWidgetNode);
                                //w.NewID();//暂时不重建ID。

                                ICanBeLinkedWidget canLinkedWidget = w as ICanBeLinkedWidget;
                                if (canLinkedWidget != null)
                                {
                                    Widgets.TriangleWidget tw = canLinkedWidget as Widgets.TriangleWidget;
                                    if (tw != null)
                                    {
                                        Point oldStartPoint = canLinkedWidget.StartPoint;
                                        Point oldEndPoint = canLinkedWidget.EndPoint;
                                        canLinkedWidget.StartPoint = new Point(oldStartPoint.X + insertPoint.X, oldStartPoint.Y + insertPoint.Y);
                                        canLinkedWidget.EndPoint = new Point(
                                            oldEndPoint.X + insertPoint.X, oldEndPoint.Y + insertPoint.Y);

                                        Point oldCenterCPPoint = tw.CenterCPPoint;
                                        tw.CenterCPPoint = new Point(insertPoint.X + oldCenterCPPoint.X,
                                            insertPoint.Y + oldCenterCPPoint.Y);
                                    }
                                    else
                                    {
                                        Point oldStartPoint = canLinkedWidget.StartPoint;
                                        Point oldEndPoint = canLinkedWidget.EndPoint;
                                        canLinkedWidget.StartPoint = new Point(w.TopLeft.X + insertPoint.X, w.TopLeft.Y + insertPoint.Y);
                                        canLinkedWidget.EndPoint = new Point(
                                            canLinkedWidget.StartPoint.X + (oldEndPoint.X - oldStartPoint.X),
                                            canLinkedWidget.StartPoint.Y + (oldEndPoint.Y - oldStartPoint.Y));
                                    }

                                    pastedCanLindedWidgets.Add(canLinkedWidget);

                                    //ICanLinkedWidget暂时不重建ID。因为需要保持与可能存在的连接线的关系，这时需要旧的ID。
                                    continue;
                                }
                                else
                                {
                                    w.NewID();//其它类型部件，先重建ID。

                                    Widgets.LineWidget lw = w as Widgets.LineWidget;
                                    if (lw != null)
                                    {
                                        lw.UpdatePointsWhenPasting(insertPoint);

                                        ILinkableLine linkableLine = lw as ILinkableLine;
                                        if (linkableLine != null)
                                        {
                                            pastedLinkableLines.Add(linkableLine);
                                            continue;
                                        }
                                    }
                                }

                                pastedOtherWidgets.Add(w);

                                Action actAddWidget = new Action(ActionType.WidgetAdded, mainPe.Id, w.Id,
                                    null, newWidgetNode.OuterXml);

                                mi.AddAction(actAddWidget);

                                mainPe.AddWidget(w);
                                w.IsSelected = true;

                                info.AddWidgetID_NewSelected(w.Id);
                            }
                        }

                        //根据ICanBeLinkedWidget来找连接线。
                        foreach (ICanBeLinkedWidget canLinkedWidget in pastedCanLindedWidgets)
                        {
                            string oldID = canLinkedWidget.Id;
                            canLinkedWidget.NewID();
                            string newID = canLinkedWidget.Id;

                            foreach (ILinkableLine linkableLine in pastedLinkableLines)
                            {
                                if (linkableLine.IsLinked)
                                {
                                    if (linkableLine.StartMasterId == oldID)
                                    {
                                        linkableLine.StartMasterId = newID;
                                    }

                                    if (linkableLine.EndMasterId == oldID)
                                    {
                                        linkableLine.EndMasterId = newID;
                                    }
                                }
                            }

                            Action actAddWidget = new Action(ActionType.WidgetAdded, mainPe.Id, canLinkedWidget.Id,
                                null, canLinkedWidget.XmlData.OuterXml);

                            mi.AddAction(actAddWidget);

                            mainPe.AddWidget(canLinkedWidget as Widgets.Widget);
                            canLinkedWidget.IsSelected = true;

                            info.AddWidgetID_NewSelected(canLinkedWidget.Id);
                        }

                        foreach (ILinkableLine linkableLine in pastedLinkableLines)
                        {
                            if (linkableLine.IsLinked == false)//非连接线，直接粘贴。
                            {
                                mainPe.AddWidget(linkableLine as Widgets.Widget);
                                linkableLine.IsSelected = true;

                                linkableLine.RefreshLocation();
                                Action actAddSw = new Action(ActionType.WidgetAdded, mainPe.Id, linkableLine.Id,
                                    null, linkableLine.XmlData.OuterXml);
                                mi.AddAction(actAddSw);

                                continue;
                            }

                            bool isStartLinked = false;
                            bool isEndLinked = false;
                            foreach (Widgets.Widget w in pastedCanLindedWidgets)
                            {
                                if (linkableLine.StartMasterId == w.Id) isStartLinked = true;

                                if (linkableLine.EndMasterId == w.Id) isEndLinked = true;
                            }

                            if (isStartLinked && isEndLinked)
                            {
                                mainPe.AddWidget(linkableLine as Widgets.Widget);

                                Action actAddSw = new Action(ActionType.WidgetAdded, mainPe.Id, linkableLine.Id,
                                    null, linkableLine.XmlData.OuterXml);
                                mi.AddAction(actAddSw);
                            }
                            else
                            {
                                mainDocWidgetSetNode.RemoveChild(linkableLine.XmlData);//去除误添加的节点。
                            }
                        }

                        int titleTextAreasCount = 0;

                        List<Widgets.Widget> newSelectedWidgets = mainPe.GetSelectedWidgetsList();
                        if (newSelectedWidgets.Count > 0)
                        {
                            info.NewMainSelectedWidgetID = newSelectedWidgets[0].Id;
                            newSelectedWidgets[0].IsMainSelected = true;

                            foreach (Widgets.Widget w in newSelectedWidgets)
                            {
                                if (w is Widgets.TextArea && w.TitleLevel != Enums.TitleStyle.Normal)
                                {
                                    titleTextAreasCount++;
                                }
                            }
                        }

                        manager.RegisterModifingItem(mi);

                        if (titleTextAreasCount > 0)//只有标题文本块才影响自动编号。
                        {
                            manager.RefreshAutoNumberStrings();
                            mi.NeedRefreshAutoNumberStrings = true;
                        }

                        //刷新连接线的位置。
                        //foreach (ILinkableLine linkableLine in pastedLinkableLines)
                        //{
                        //    if (linkableLine.IsLinked == false)
                        //        continue;

                        //    linkableLine.RefreshLocation();
                        //}
                    }
                    else
                    {
                        if (text.Length > 1000) return "　　剪贴板中的文本长度超过了1000，无法粘贴成矩形文本框中。";
                        //如果是不可识别的文本，直接在插入点位置添加一个矩形，并将剪贴板中的文本设置为其内容，长度限制为1000

                        if (mainPe.EditArea.Contains(mainPe.BaseInsertPoint) == false) return "　　活动页面插入点位置过于靠边，不在可编辑区域内，不能粘贴！";

                        XmlNode widgetSetNode = mainPe.WidgetSetNode;
                        if (widgetSetNode == null)
                        {
                            return "　　未找到WidgetSet节点，无法添加矩形。";
                        }

                        //<Widget Type="Rectangle">
                        //    <ParagraphSet xml:space="preserve">
                        //        <Paragraph>
                        //            <Text />
                        //        </Paragraph>
                        //    </ParagraphSet>
                        //</Widget>

                        XmlNode newNode = widgetSetNode.AppendXmlAsChild("<Widget Type=\"Rectangle\"><ParagraphSet xml:space=\"preserve\"><Paragraph><Text>" +
                            XmlTools.ReplaceXmlChars(text).Replace("\r", "").Replace("\n", "</Text></Paragraph><Paragraph><Text>") + "</Text></Paragraph></ParagraphSet></Widget>");

                        Widgets.RectangleWidget rw = new Widgets.RectangleWidget(mainPe);
                        rw.XmlData = newNode;
                        rw.NewID();
                        rw.StartPoint = mainPe.BaseInsertPoint;

                        if (mainPe.ActualHeight > mainPe.ActualWidth)
                        {
                            rw.EndPoint = new Point(rw.StartPoint.X + mainPe.ActualWidth / 2, rw.StartPoint.Y + mainPe.ActualHeight / 4);
                        }
                        else
                        {
                            rw.EndPoint = new Point(rw.StartPoint.X + mainPe.ActualWidth / 4, rw.StartPoint.Y + mainPe.ActualHeight / 2);
                        }

                        rw.FixTextWidth = true;

                        //按默认值设置属性
                        //rw.WidgetOpacity = manager.RectangleStyle.WidgetOpacity;
                        //rw.WidgetForeColor = manager.RectangleStyle.WidgetForeColor;
                        //rw.WidgetBackColor = manager.RectangleStyle.WidgetBackColor;
                        //rw.WidgetLineColor = manager.RectangleStyle.WidgetLineColor;
                        //rw.WidgetLineWidth = manager.RectangleStyle.WidgetLineWidth;
                        //rw.LineDash = manager.RectangleStyle.LineDash;
                        //rw.IsShadowVisible = manager.RectangleStyle.IsShadowVisible;

                        ModifingInfo info = new ModifingInfo() { ModifingDescription = "粘贴文本为矩形文本块" };
                        mainPe.MasterManager.GetSelectedPageEditorStatus(info);
                        mainPe.MasterManager.GetSelectedWidgetStatus_Old(info);
                        ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

                        Action actionAddRectangle = new Action(ActionType.WidgetAdded,
                            mainPe.Id, rw.Id, null, rw.XmlData.OuterXml);

                        mainPe.AddWidget(rw);

                        rw.SelectOnlySelf();

                        info.NewMainSelectedWidgetID = rw.Id;
                        mi.AddAction(actionAddRectangle);

                        if (mainPe.MasterManager != null)
                        {
                            mainPe.MasterManager.RegisterModifingItem(mi);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return "　　发生意外，未能取出剪贴板中的数据！系统剪贴板可能被其它程序占用。" +
                    "异常信息如下：\r\n" + ex.Message + "\r\n" + ex.StackTrace;
            }

            return string.Empty;
        }

        private static string InserdCopiedBackConceptPage(EditorManager manager, PageEditor mainPe, string copiedBackXmlText)
        {
            //应该是个被复制到《Lunar Mind》中的页面，
            try
            {
                if (string.IsNullOrEmpty(copiedBackXmlText)) throw new ArgumentNullException("copiedBackXmlText");

                var startIndex = copiedBackXmlText.IndexOf("<Page");
                copiedBackXmlText = copiedBackXmlText.Substring(startIndex);

                var endIndex = copiedBackXmlText.LastIndexOf("</Page>");
                copiedBackXmlText = copiedBackXmlText.Substring(0, endIndex + 7);

                if (startIndex < 0 || endIndex < 0) return "数据无法解析！";

                //将从《Lunar Mind》中复制回来的Page插入到当前页面之前。

                XmlNode pageSetNode = manager.XmlDocument.DocumentElement.SelectSingleNode(XmlTags.PageSetTag);

                if (pageSetNode == null)
                {
                    pageSetNode = manager.XmlDocument.DocumentElement.
                        AppendXmlAsChild(string.Format("<{0} />", XmlTags.PageSetTag));
                }

                if (manager.Count >= 500)
                {
                    MessageBoxResult r = MessageBox.Show("　　天哪！竟然超过500页！这太难想像了。真的要继续吗？",
                        Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);

                    if (r != MessageBoxResult.Yes) return string.Empty;
                }

                PageEditor basePageEditor = mainPe;
                XmlNode newPageNode = null;

                if (basePageEditor.XmlData.InsertXml(copiedBackXmlText, true))
                {
                    newPageNode = basePageEditor.XmlData.NextSibling;

                    //重建ID
                    InsertPageCopyEditorCommand.RebuildIDsOfWidgetsInPageOrGroup(newPageNode);
                }

                if (newPageNode == null) return "　　未能顺利添加新页面节点。";

                PageEditor newPageEditor = new PageEditor(manager);
                newPageEditor.XmlData = newPageNode;
                newPageEditor.NewID();
                newPageEditor.PaperDirection = basePageEditor.PaperDirection;
                //newPageEditor.PaperSize = basePageEditor.PaperSize;//不能使用这个！！！

                int newIndex = manager.InsertAfter(basePageEditor, newPageEditor);

                ModifingInfo info = new ModifingInfo();

                //记录操作前被选定的所有PageEditor的ID。
                List<PageEditor> oldSelectedPageEditorList = manager.GetSelectedPageEditorsList();
                foreach (PageEditor pe in oldSelectedPageEditorList)
                {
                    info.AddPageEditorID_OldSelected(pe.Id);
                    if (pe.IsMainSelected)
                    {
                        info.OldMainSelectedPageEditorID = pe.Id;
                    }

                    if (pe.IsSelected) pe.IsSelected = false;
                }
                manager.GetSelectedWidgetStatus_Old(info);
                manager.GetSelectedWidgetStatus_New(info);

                info.ModifingDescription = "粘贴页";

                //记录操作后被选定的（其实就是新添加的PageEditor的ID）。
                info.NewMainSelectedPageEditorID = newPageEditor.Id;
                newPageEditor.IsMainSelected = true;

                ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

                Action actAddPageEditor = new Action(ActionType.PageEditorAdded, newPageEditor.Id, newIndex, null,
                    newPageEditor.XmlData.OuterXml);
                mi.AddAction(actAddPageEditor);

                manager.RegisterModifingItem(mi);
                manager.RefreshPaginations();
                manager.TryToDisplayPageEditor(newPageEditor, false);

                manager.MasterWindow.RefreshPageView();

                return string.Empty;
            }
            catch (Exception ex)
            {
                return "　　发生意外，数据解析错误。" +
                    "异常信息如下：\r\n" + ex.Message + "\r\n" + ex.StackTrace;
            }
        }

        private static bool PasteImageData(System.Drawing.Image oImgObj)
        {
            if (Globals.MainWindow == null) return false;
            EditorManager manager = Globals.MainWindow.EditorManager;
            if (manager == null) return false;

            PageEditor pageEditor = manager.GetMainSelectedPageEditor();
            if (pageEditor == null) return false;

            using (MemoryStream stm = new MemoryStream())
            {
                if (oImgObj == null)
                {
                    MessageBox.Show("　　未能顺利取出剪贴板中的图像数据！"
                        + "请将图片加工一下或另选一张图片。",
                            Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return false;
                }

                // 准备“撤销”与“重做”所需要的数据。
                ModifingInfo info = new ModifingInfo() { ModifingDescription = "粘贴图像" };
                manager.GetSelectedPageEditorStatus(info);
                manager.GetSelectedWidgetStatus_Old(info);
                //是否刷新GetSelectedWidgetStatus_New(info)要根据情况决定。

                ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

                Widgets.PictureBox pb = null;

                Widgets.Widget mainWidget = pageEditor.GetMainSelectedWidget();
                if (mainWidget == null) //现在，每种部件其实都支持背景图了。 || (mainWidget is Widgets.PictureBox) == false)
                {
                    //新建PictureBox
                    pb = new Widgets.PictureBox(pageEditor);
                    XmlNode peWidgetSetNode = pageEditor.WidgetSetNode;
                    if (peWidgetSetNode == null)
                    {
                        MessageBox.Show("　　未找到目标页面的后台WidgetSet节点。", Globals.AppName,
                               MessageBoxButton.OK, MessageBoxImage.Warning);
                        return false;
                    }

                    XmlNode newPictureBoxNode = peWidgetSetNode.AppendXmlAsChild(Properties.Resources.PictureBoxXml);

                    XmlNode imageBase64Node = newPictureBoxNode.SelectSingleNode(XmlTags.ImageBase64Tag);

                    oImgObj.Save(stm, System.Drawing.Imaging.ImageFormat.Png);//默认以png格式保存
                    if (stm.Length > 10485760)
                    {
                        MessageBox.Show("　　为防止文档体积过分庞大，图片框只支持文件尺寸在 10 MB 以下的图片！"
                            + "请将图片加工一下或另选一张图片。",
                                Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                        return false;
                    }

                    byte[] b = stm.GetBuffer();
                    string imgDataText = Convert.ToBase64String(b);

                    if (imageBase64Node == null)
                    {
                        newPictureBoxNode.AppendXmlAsChild("<" + XmlTags.ImageBase64Tag + ">" + imgDataText + "</" + XmlTags.ImageBase64Tag + ">");
                    }
                    else
                    {
                        imageBase64Node.InnerText = imgDataText;
                    }

                    pb.XmlData = newPictureBoxNode;
                    pb.NewID();
                    pb.Location = pageEditor.BaseInsertPoint;
                    Action actAddPictureBox = new Action(ActionType.WidgetAdded, pageEditor.Id, pb.Id, null, pb.XmlData.OuterXml);

                    pageEditor.AddWidget(pb);
                    pb.RefreshLocation();
                    pb.SelectOnlySelf();

                    mi.AddAction(actAddPictureBox);

                    info.NewMainSelectedWidgetID = pb.Id;
                    manager.RegisterModifingItem(mi);

                    //只有标题文本块被粘贴才有必要刷新自动编号
                    //manager.RefreshAutoNumberStrings();
                    return true;
                }
                else
                {
                    XmlNode imageBase64Node;
                    //bool isPicbox = false;
                    //if (mainWidget is Widgets.PictureBox)   // 分开的方案有个大问题：会导致设置部件背景色后无法撤销！！！
                    //{
                    //isPicbox = true;
                    imageBase64Node = mainWidget.XmlData.SelectSingleNode(XmlTags.ImageBase64Tag);
                    //}
                    //else
                    //    imageBase64Node = mainWidget.XmlData.SelectSingleNode(XmlTags.ImageBase64Tag); //(XmlTags.BackgroundImageBase64Tag);

                    oImgObj.Save(stm, System.Drawing.Imaging.ImageFormat.Png);//默认以png格式保存
                    if (stm.Length > 10485760)
                    {
                        MessageBox.Show("　　为防止文档体积过分庞大，图片框只支持文件尺寸在 10 MB 以下的图片！"
                            + "请将图片加工一下或另选一张图片。",
                                Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                        return false;
                    }

                    byte[] b = stm.GetBuffer();
                    string imgDataText = Convert.ToBase64String(b);

                    string oldImgBase64Text = null;

                    var tag = XmlTags.ImageBase64Tag;   //isPicbox ? XmlTags.ImageBase64Tag : XmlTags.BackgroundImageBase64Tag;
                    if (imageBase64Node == null)
                    {
                        oldImgBase64Text = string.Empty;

                        mainWidget.XmlData.AppendXmlAsChild("<" + tag + ">" + imgDataText + "</" + tag + ">");
                    }
                    else
                    {
                        oldImgBase64Text = imageBase64Node.InnerText;
                        imageBase64Node.InnerText = imgDataText;
                    }

                    Action actImg = new Action(pageEditor.Id, mainWidget.Id, mainWidget.GetType().Name, tag,
                        oldImgBase64Text, imgDataText);

                    mainWidget.ImageBase64 = imgDataText;

                    mainWidget.Build();

                    manager.GetSelectedWidgetStatus_New(info);

                    mi.AddAction(actImg);
                    manager.RegisterModifingItem(mi);

                    //只有标题文本块被粘贴才有必要刷新自动编号。
                    //manager.RefreshAutoNumberStrings();

                    return true;
                }
            }
        }

        #endregion
    }
}
